iT邦幫忙

2025 iThome 鐵人賽

DAY 8
0

前言

今天我們將實作如何從零開始配置 Redis Client 到 SpringBoot 模組。現在目前使用 JVM 記憶體儲存實現限流功能,接下幾天將整合 Redis 來提升系統的可擴展性和持久性。透過 Redis 的整合,我們可以實現分散式限流,讓多個應用實例共享限流狀態。

實作 Lab:Redis Client 基礎配置

首先,我們需要在 pom.xml 中添加 Redis 相關的依賴:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>

Docker Compose

然後之前我有用 Docker Compose 來啟動我的 MySQL Server,Redis 也可以用同樣的方式做配置,到時就可以直接在容器裡運行 Redis Server,首先設置一下環境變數:

# Redis Configuration
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=redis123456
REDIS_DATABASE=0
REDIS_TIMEOUT=2000
REDIS_POOL_MAX_TOTAL=20
REDIS_POOL_MAX_IDLE=10
REDIS_POOL_MIN_IDLE=5

docker-compose.yaml

version: "3.8"
services:
  mysql:
    # skip...
  redis:
    image: redis:7-alpine
    container_name: core-redis
    ports:
      - "${REDIS_PORT:-6379}:6379"
    volumes:
      - redis_data:/data
    restart: unless-stopped
    command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}

volumes:
  mysql_data:
  redis_data:

實際啟動容器:

docker compose up -d redis

登入看看:

redis-cli -a redis123456

然後 ping 看看可不可以連到 Redis:

127.0.0.1:6379> ping
PONG

大功告成!

application.yaml

再來是 SpringBoot 的配置:

spring:
  application:
    name: playground-module

  datasource:
    url: jdbc:h2:mem:testdb
    driver-class-name: org.h2.Driver
    username: sa
    password:

  jpa:
    hibernate:
      ddl-auto: create-drop
    show-sql: true

	# Redis Configuration
  data:
    redis:
      host: ${REDIS_HOST:localhost}
      port: ${REDIS_PORT:6379}
      password: ${REDIS_PASSWORD:}
      database: ${REDIS_DATABASE:0}
      timeout: ${REDIS_TIMEOUT:2000}ms
      lettuce:
        pool:
          max-active: ${REDIS_POOL_MAX_TOTAL:20}
          max-idle: ${REDIS_POOL_MAX_IDLE:10}
          min-idle: ${REDIS_POOL_MIN_IDLE:5}
          max-wait: -1ms

RedisConfig

這個 config 類是為 Redis Client 在 SpringBoot 專案內使用方式做定義

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(connectionFactory);

        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();

        redisTemplate.setKeySerializer(stringRedisSerializer);
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

}

測試類:RedisHelper

這是為了簡單測試做的類別,用途是訪問 Redis Server,有點像是用來操作 Redis 的工具類的概念:

@Component
@RequiredArgsConstructor
public class RedisHelper {

    private final RedisTemplate<String, Object> redisTemplate;

    public Long increment(String cacheName, Object... keys) {
        return redisTemplate.opsForValue().increment(cacheName.concat(":").concat(String.valueOf(keys)));
    }
}

接著到 Controller 調用看看,然後實際發個 api call 測試有沒有把資料寫進 Redis,並且返回 Redis 裡的資料:

@GetMapping(value = "/redis")
public ResponseEntity<Long> getRedisCount() {
    return ResponseEntity.ok(redisHelper.increment(RedisKey.RATE_LIMITER.getValue(), RequestContextHelper.getClientIp()));
}

測試成功!調用後確認 Redis 裡資料被寫入了,只是 key 之後還要細調,但這次就只是單純做個類似 PoC 的動作:

https://ithelp.ithome.com.tw/upload/images/20250829/20161582VAH9xPqEz2.png

總結

最近幾天工作上有點繁忙,文章的質量稍嫌下降,今天也是在最後關頭,趕快在一個多小時內生出這篇文章,壓線維持住當前的紀錄,還好明天就週末了,一定要在週末加把勁,多做多寫一點,加油!


上一篇
Day 7 | 限流器實作:Redis 實現分散式限流策略之前導
下一篇
Day 9 | 限流器實作:測試限流計數共享|運行兩個實例
系列文
系統設計一招一式:最基本的功練到爛熟就是殺手鐧,從單體架構到分布式系統的 Lab 實作筆記14
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言